package net.alche.al.util.far.pojo;

import net.alche.al.util.AC;
import net.alche.al.util.Far;
import net.alche.al.util.M;
import net.alche.fa.core.CodeLevel;
import net.alche.fa.core.FaException;
import net.alche.fa.core.SageStone;
import net.alche.fa.core.model.FaValue;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings("all")
public class VueFunction {
    public int uniId = 0;
    public Map<String, Object> zzInnerMap;
    Map<String, Object> zzParams = null;
    // Object zzThis;
    VueFunctionImp back;
    SageStone back2;
    boolean onThenCall = false;

    // public VueFunction(Object zzThis) {
    // this.zzThis = zzThis;
    // }

    public VueFunction() {
    }

    public VueFunction(Object... vals) {
        if (vals != null && vals.length > 0) {
            this.zzParams = new HashMap<>();
            if (vals != null) {
                int i = 0;
                for (Object obj : vals) {
                    this.zzParams.put("" + i++, obj);
                }
            }
        }
    }

    public void setValus(Object... vals) {
        if (this.zzParams == null) {
            this.zzParams = new HashMap<>();
        }
        if (vals != null) {
            int i = 0;
            for (Object obj : vals) {
                this.zzParams.put("" + i++, obj);
            }
        }
    }

    public VueFunction(Object zzThis, String[] paramNames, Object[] paramVals) {
        // this.zzThis = zzThis;
        this.zzInnerMap = new HashMap<>();
        for (int i = 0; i < paramNames.length; i++) {
            this.zzInnerMap.put(paramNames[i], paramVals[i]);
        }
    }

    public void setListener(VueFunctionImp back) {
        this.back = back;
    }

    public VueFunction then(SageStone back2) {
        this.back2 = back2;
        if (this.onThenCall) {
            this.onThenCall = false;
            toFaCall();
        }
        return this;
    }

    void toFaCall() {
        List<FaValue> pars = new ArrayList<>();
        pars.add(new FaValue(this));
        try {
            CodeLevel lvl = new CodeLevel();
            lvl.uuid = "VueFuncton";
            this.back2.getFaClass().call("onCall", pars, lvl);
        } catch (FaException e) {
            e.printStackTrace();
        }
    }

    public VueFunction then(VueFunctionImp back) {
        this.back = back;
        if (this.onThenCall) {
            this.onThenCall = false;
            this.back.onCall(this);
        }
        return this;
    }

    public void call() {
        if (back != null) {
            back.onCall(this);
        }
        if (this.back2 != null) {
            toFaCall();
        }

    }

    public void callOnThen() {
        this.call();
        this.ckOnThen();
    }

    public void ckOnThen() {
        if (back == null && back2 == null) {
            this.onThenCall = true;
        }
    }

    public void call(String key, Object val) {
        if (this.zzParams == null) {
            this.zzParams = new HashMap<>();
        }
        this.zzParams.put(key, val);
        this.zzParams.put("0", val);
        if (back != null) {
            back.onCall(this);
        }
    }

    public void callVals(Object... vals) {
        setValus(vals);
        if (back != null) {
            back.onCall(this);
        }
        if (back2 != null) {
            toFaCall();
        }
    }

    public void callValsOnThen(Object... vals) {
        this.callVals(vals);
        this.ckOnThen();
    }

    public void call(VueFunction fun) {
        zzParams = fun.zzParams;
        if (back != null) {
            back.onCall(this);
        }
        if (back2 != null) {
            toFaCall();
        }
    }

    public void call(Map<String, Object> zzParams) {
        this.zzParams = zzParams;
        if (back != null) {
            back.onCall(this);
        }
        if (back2 != null) {
            toFaCall();
        }
    }

    public <T> T getParam(String key) {
        if (this.zzParams != null && this.zzParams.containsKey(key)) {
            return (T) this.zzParams.get(key);
        }
        return null;
    }

    public <T> T getParam(Integer index) {
        if (this.zzParams != null && this.zzParams.containsKey("" + index)) {
            return (T) this.zzParams.get("" + index);
        }
        return null;
    }

    public <T> T get(int index) {
        return this.getParam(index);
    }

    public <T> T get(int index, Class cls) {
        Object obj = this.getParam(index);
        if (cls != null && obj != null) {
            return (T) M.transVal(obj, cls);
        }
        return (T) obj;
    }

    public ResultPack getResultPack(Type type) {
        try {
            String jsonTxt = getParam("response");
            return Far.gson.fromJson(jsonTxt, type);// new TypeToken<ResultPack<ArrayList<ExpOrderList.OdpTask>>>()
                                                    // {}.getType()
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return new ResultPack();
    }
}
